package product.type;

import models.BaseModel;
import models.constants.AvailableStatus;
import models.constants.DeletedStatus;
import models.enums.TreeNodeStatus;
import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;
import product.ProductTypes;
import util.common.ConvertUtil;

import javax.persistence.*;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by buhaoba on 16/6/13.
 */
@Entity
@Table(name = "product_type")
public class ProductType extends BaseModel {

    /**
     * 类别名称
     */
    @Column(name = "name")
    public String name;

    /**
     * 末端节点
     */
    @Column(name = "is_leaf")
    public int isLeaf;
    /**
     * 是否为叶子节点 open:叶子节点 close:非叶子节点
     */
    @Transient
    public TreeNodeStatus state;
    /**
     * 等级
     */
    @Column(name = "level")
    public Integer level;
    /**
     * 所属类别
     */
    @Column(name = "parent_type_id")
    public Long parentTypeId;

    /**
     * 节点全路径
     */
    @Column(name = "node_id_path")
    public String nodeIdPath;

    /**
     * 排序号
     */
    @Column(name = "sort")
    public Integer sort;

    @Transient
    public Integer isModify;

    @Transient
    public Integer isCheck;

    /**
     * 当前状态  禁用\可用
     */
    @Enumerated(EnumType.STRING)
    public AvailableStatus status;

    /**
     * 逻辑删除,0:未删除，1:已删除
     */
    @Enumerated(EnumType.ORDINAL)
    public DeletedStatus deleted;

    /**
     * 备注
     */
    @Column(name = "remark")
    public String remark;


    public ProductType(String name) {
        this.createAt = new Date();
        this.deleted = DeletedStatus.UN_DELETED;
        this.parentTypeId = new Long(0);
        this.status = AvailableStatus.AVAILABLE;
        this.isLeaf = 1;
        this.level = 1;
    }

    /**
     * 根据层级查找产品类型
     * @return
     */
    public static List<ProductType> findProductTypeByLevel(Integer level){
        return find("deleted = ? and status = ? and level = ? order by sort",DeletedStatus.UN_DELETED,AvailableStatus.AVAILABLE,level).fetch();
    }

    /**
     * 查看可用 类别
     *
     * @return
     */
    public static List<ProductType> findAvailable() {
        return find("deleted = ? and status = ? order by sort", DeletedStatus.UN_DELETED, AvailableStatus.AVAILABLE).fetch();
    }

    /**
     * 根据类别查看
     *
     * @return
     */
    public static List<ProductType> findAvailable(AvailableStatus status) {
        return find("deleted = ? and status = ? order by sort", DeletedStatus.UN_DELETED, status).fetch();
    }

    /**
     * 加载产品类型树
     *
     * @return
     */
    public static List<ProductType> loadTypeTree(Long id, long productId) {
        Query query = em().createNativeQuery("SELECT distinct t.id,t.sort,t.parent_type_id as parentTypeId,t.name,case when p.id is null THEN 0 else 1 end as 'isCheck',t.level,t.is_leaf as isLeaf ,t.status,case when is_leaf = 1 then 'open' else 'closed' end as 'state'  from product_type t LEFT JOIN product_types p ON t.id = p.type_id and p.product_id = " + productId + " where t.deleted = 0 and t.status = 'AVAILABLE' and t.parent_type_id = " + id + " order by t.sort asc,id desc");
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        return query.getResultList();
    }

    /**
     * 加载产品类型树
     */
    public static List loadTypeTree(Long id) {
        List<ProductType> productTypes = ProductType.find(" deleted = ? and parentTypeId = ? order by sort asc,id desc ", DeletedStatus.UN_DELETED, id).fetch();
        for (ProductType productType : productTypes) {
            productType.state = productType.isLeaf == 1 ? TreeNodeStatus.open : TreeNodeStatus.closed;
        }
        return productTypes;
    }

    /**
     * 加载可用的一级节点
     *
     * @return
     */
    public static List<ProductType> findChildNode(long id) {
        return ProductType.find(" parentTypeId = ? and status = ? and deleted = ? order by sort asc", id, AvailableStatus.AVAILABLE, DeletedStatus.UN_DELETED).fetch();
    }

    //根据ID删除操作明细
    public static void delByIds(Long[] delItemArray) {
        if (delItemArray != null) {
            for (Long typeId : delItemArray) {
                ProductType productType = ProductType.findById(typeId);
                productType.deleted = DeletedStatus.DELETED;
                productType.save();
            }
        }
    }


    /**
     * 判断productType是否被使用
     */
    public static String checkIsUsed(Long[] delItemArray) {
        String str = "销售类型:";
        if (delItemArray != null) {
            for (long typeId : delItemArray) {
                boolean check = ProductTypes.count(" type.id=? and deleted=?", typeId, DeletedStatus.UN_DELETED) > 0;
                if (check) {
                    ProductType productType = ProductType.findById(typeId);
                    str += ConvertUtil.toString(productType.name) + ",";
                }
            }
        }
        return str;
    }

    /**
     * 查询类型树
     */
    public static List<Map> loadProductTypeTree(long id) {
        String sqlSelect = "Select id,name as 'text',node_id_path,is_leaf,remark,case when is_leaf = 1 then 'open' else 'closed' end as 'state' from product_type where deleted=0 and parent_type_id =" + id;
        Query query = ProductType.em().createNativeQuery(sqlSelect);
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        return query.getResultList();
    }

//    /**
//     * 根据 parentId 查询类别
//     * @param parentId
//     * @return
//     */
//    public static ProductType getParent(Long parentId) {
//        if(ObjectUtil.checkNotBlock(parentId)) {
//            return ProductType.findById(parentId);
//        }
//        return null;
//    }
//
//    /**
//     * 根据 父类别 Id 查询 类别
//     * @param parentId
//     * @return
//     */
//    public static List<ProductType> findByType(Long parentId) {
//        if(ObjectUtil.checkNotBlock(parentId)) {
//            return ProductType.find("parentId = ? and deleted = ? and status = ?" , parentId , DeletedStatus.UN_DELETED , AvailableStatus.AVAILABLE).fetch();
//        }
//        return null;
//    }

}
